<template>
  <n-card style="padding: 0" :content-style="{ padding: 0 }" mb-30 :bordered="false">
  <QueryBar v-if="$slots.queryBar"  @search="handleSearch" @reset="handleReset">
    <slot name="queryBar" />
    <template #action>
      <slot name="action" />
    </template>
  </QueryBar>
  </n-card>

  <n-card  style="padding-bottom: 10px;border-radius: 10px;" :bordered="false" :content-style="{ padding: 0 }">
  <n-data-table
    :remote="remote"
    :loading="loading"
    :columns="columns"
    :data="tableData"
    :scroll-x="scrollX"
    :row-key="(row) => row[rowKey]"
    :pagination="isPagination ? pagination : false"
    @update:checked-row-keys="onChecked"
    @update:page="onPageChange"
    striped
    size="small"
    :expand-all="true"
    single-column="false"
    single-line="false"
    :bordered="false"
    :bottom-bordered="false"
    :style="{ borderRadius: '10px' }"
    :max-height="data.table_height"
    :header-class-name="() => 'white-header'"
    :virtual-scroll="shouldUseVirtualScroll"
  />
  </n-card>
</template>

<script setup>
import { ref, reactive, computed, nextTick } from 'vue'

const props = defineProps({
  /**
   * @remote true: 后端分页  false： 前端分页
   */
  remote: {
    type: Boolean,
    default: true,
  },
  maxheight: {
    type: Number,
    default:370,
  },
  /**
   * @remote 是否分页
   */
  isPagination: {
    type: Boolean,
    default: true,
  },
  /**
   * @virtualScroll 是否启用虚拟滚动（大数据量时使用）
   */
  virtualScroll: {
    type: Boolean,
    default: false,
  },
  scrollX: {
    type: Number,
    default: 450,
  },
  rowKey: {
    type: String,
    default: 'id',
  },
  columns: {
    type: Array,
    required: true,
  },
  /** queryBar中的参数 */
  queryItems: {
    type: Object,
    default() {
      return {}
    },
  },
  /** 补充参数（可选） */
  extraParams: {
    type: Object,
    default() {
      return {}
    },
  },
  /**
   * ! 约定接口入参出参
   * * 分页模式需约定分页接口入参
   *    @page_size 分页参数：一页展示多少条，默认10
   *    @page   分页参数：页码，默认1
   */
  getData: {
    type: Function,
    required: true,
  },
})

const data = reactive({
  table_height:window.innerHeight - props.maxheight
})

const emit = defineEmits(['update:queryItems', 'onChecked', 'onDataChange'])
const loading = ref(false)
const initQuery = { ...props.queryItems }
const tableData = ref([])

// 根据数据量自动启用虚拟滚动（当数据量大于100条时启用）
const shouldUseVirtualScroll = computed(() => {
  if (props.virtualScroll !== undefined) {
    return props.virtualScroll
  }
  // 如果数据量大于100条，自动启用虚拟滚动
  return tableData.value.length > 100
})
const pagination = reactive({
  page: 1,
  page_size: 20,
  // 限制最大每页条数，避免性能问题
  pageSizes: [20, 50, 100, 200, 500],
  showSizePicker: true,
  prefix({ itemCount }) {
    return `共 ${itemCount} 条`
  },
  onChange: (page) => {
    pagination.page = page
  },
  onUpdatePageSize: (pageSize) => {
    pagination.page_size = pageSize
    pagination.page = 1
    handleQuery()
  },
})

async function handleQuery() {
  let totalAmount = null
  try {
    loading.value = true
    let paginationParams = {}
    // 如果非分页模式或者使用前端分页,则无需传分页参数
    if (props.isPagination && props.remote) {
      paginationParams = { page: pagination.page, page_size: pagination.page_size }
    }
    const { data, total, total_amount } = await props.getData({
      ...props.queryItems,
      ...props.extraParams,
      ...paginationParams,
    })
    tableData.value = data
    pagination.itemCount = total || 0
    totalAmount = total_amount
  } catch (error) {
    tableData.value = []
    pagination.itemCount = 0
  } finally {
    console.log('[CrudTable] totalAmount:', totalAmount)
    emit('onDataChange', tableData.value, typeof totalAmount !== 'undefined' ? totalAmount : null)
    loading.value = false
  }
}
function handleSearch() {
  pagination.page = 1
  handleQuery()
}
function handlerefresh() {
  handleQuery()
}
async function handleReset() {
  const queryItems = { ...props.queryItems }
  for (const key in queryItems) {
    queryItems[key] = ''
  }
  emit('update:queryItems', { ...queryItems, ...initQuery })
  await nextTick()
  pagination.page = 1
  handleQuery()
}
function onPageChange(currentPage) {
  pagination.page = currentPage
  if (props.remote) {
    handleQuery()
  }
}
function onChecked(rowKeys) {
  if (props.columns.some((item) => item.type === 'selection')) {
    emit('onChecked', rowKeys)
  }
}

defineExpose({
  handleSearch,
  handleReset,
  tableData,
  handlerefresh
})
</script>

